<template>
	<view>
		<view class="wrapper">
			<view class="handBtn">
				<button @click="clear" type="success" class="delBtn">清空</button>
				<button @click="saveCanvasAsImg" type="info" class="saveBtn">保存</button>
				<button @click="previewCanvasImg" type="warning" class="previewBtn">预览</button>
				<button @click="undo" type="error" class="undoBtn">撤销</button>
				<button @click="complete" type="primary" class="subCanvas">完成</button>
			</view>
			<view class="handCenter">
				<canvas 
					canvas-id="handWriting" 
					id="handWriting"
					class="handWriting" 
					:disable-scroll="true" 
					@touchstart="uploadScaleStart"
					@touchmove="uploadScaleMove" 
					@touchend="uploadScaleEnd"
					></canvas>
			</view>
			<view class="handRight">
				<view class="handTitle">请签名</view>
			</view>
		</view>
	</view>
</template>
 
<script>
// 导入工具类
import { UploadManager } from '../../utils/uploadManager.js'
import { showToast, showLoading, hideLoading, formatErrorMessage, showFinalError, showModal } from '../../utils/messageUtils.js'
import { deepMerge, validateConfig, validateUrl, validateFileType, validateQuality, validateTimeout, validateFileName, validateHeaders, validateFormData } from '../../utils/validationUtils.js'
import { calculateDistance, calculateSpeed, calculateLineWidth, getRadianData, getRadianPoints, toFixed, clamp, lerp } from '../../utils/mathUtils.js'
import { getCanvasSize, isCanvasReady, clearCanvasArea, setCanvasStyle, screenToCanvas, getDefaultCanvasSize, createCanvasContext, canvasToTempFile, isCanvasEmpty } from '../../utils/canvasUtils.js'
 
export default {
	data() {
		return {
			ctx: '',
			canvasWidth: 0,
			canvasHeight: 0,
			lineColor: '#1A1A1A',
			points: [],
			historyList: [],
			drawingHistory: [],
			currentStroke: [],
			canAddHistory: true,
			isCanvasReady: false,
 
			mergedConfig: {},
			uploadManager: null,
			defaultConfig: {
				uploadUrl: '',
				headers: {
					'Content-Type': 'multipart/form-data'
				},
				formData: {},
				fileName: 'signature',
				fileType: 'png',
				quality: 1,
				timeout: 30000,
				retryCount: 2,
				retryDelay: 1000,
				showErrorToast: true,
				errorToastDuration: 3000,
				enableAutoRetry: true,
				retryOnNetworkError: true,
				retryOnServerError: false
			},
			getImagePath: () => {
				return new Promise((resolve) => {
					uni.canvasToTempFilePath({
						canvasId: 'handWriting',
						fileType: 'png',
						quality: 1, //图片质量
						success: res => resolve(res.tempFilePath),
					})
				})
			},
			toDataURL: void 0,
			requestAnimationFrame: void 0,
		};
	},
	props: {
		minSpeed: {
			type: Number,
			default: 1.5
		},
		minWidth: {
			type: Number,
			default: 3,
		},
		maxWidth: {
			type: Number,
			default: 10
		},
		openSmooth: {
			type: Boolean,
			default: true
		},
		maxHistoryLength: {
			type: Number,
			default: 20
		},
		maxWidthDiffRate: {
			type: Number,
			default: 20
		},
		bgColor: {
			type: String,
			default: 'transparent'
		},
		uploadUrl: {
			type: String,
			default: '',
			validator: function (value) {
				if (!value) return true;
				try {
					new URL(value);
					return true;
				} catch {
					return false;
				}
			}
		},
		uploadConfig: {
			type: Object,
			default: () => ({
				headers: {
					'Content-Type': 'multipart/form-data'
				},
				formData: {
					timestamp: Date.now()
				},
				fileName: 'signature',
				fileType: 'png',
				quality: 1,
				timeout: 30000
			}),
			validator: function (value) {
				return value && typeof value === 'object';
			}
		},
	},
	methods: {
		// 配置管理方法
		// 合并配置（用户配置 + 默认配置）
		mergeConfig() {
			try {
				// 深拷贝默认配置
				const baseConfig = JSON.parse(JSON.stringify(this.defaultConfig));
 
				// 处理用户传入的配置
				const userConfig = {
					uploadUrl: this.uploadUrl,
					...this.uploadConfig
				};
 
				// 使用工具类合并配置
				this.mergedConfig = deepMerge(baseConfig, userConfig);
 
				// 使用工具类验证配置
				validateConfig(this.mergedConfig);
 
			} catch (error) {
				this.mergedConfig = JSON.parse(JSON.stringify(this.defaultConfig));
			}
		},
 
		// 新增：获取当前有效配置
		getCurrentConfig() {
			if (!this.mergedConfig || Object.keys(this.mergedConfig).length === 0) {
				this.mergeConfig();
			}
			return this.mergedConfig;
		},
		// 检查canvas上下文是否可用
		checkCanvasContext() {
			if (!this.ctx) {
				this.initCanvas();
				return false;
			}
			return true;
		},
		initCanvas() {
			try {
				this.ctx = uni.createCanvasContext("handWriting", this);
				if (this.ctx) {
					this.$nextTick(() => {
						uni.createSelectorQuery().select('.handCenter').boundingClientRect(rect => {
							if (rect && rect.width > 0 && rect.height > 0) {
								this.canvasWidth = rect.width;
								this.canvasHeight = rect.height;
							} else {
								const systemInfo = uni.getSystemInfoSync();
								this.canvasWidth = Math.floor(systemInfo.windowWidth * 0.85);
								this.canvasHeight = Math.floor(systemInfo.windowHeight * 0.95);
							}
							try {
								if (this.bgColor && this.bgColor !== 'transparent') {
									this.drawBgColor();
								}
								this.isCanvasReady = true;
							} catch (error) {
								this.isCanvasReady = false;
							}
						}).exec();
					});
				} else {
					setTimeout(() => this.initCanvas(), 500);
				}
			} catch (error) {
				setTimeout(() => this.initCanvas(), 500);
			}
		},
		uploadScaleStart(e) {
			if (!this.isCanvasReady) {
				this.initCanvas();
				return;
			}
			if (!this.checkCanvasContext()) {
				return;
			}
			this.canAddHistory = true;
 
			try {
				this.ctx.setStrokeStyle(this.lineColor);
				this.ctx.setLineCap("round");
			} catch (error) {
				console.error('设置画笔样式失败:', error);
			}
		},
		uploadScaleMove(e) {
			if (!this.isCanvasReady) {
				return;
			}
 
			let temX = e.changedTouches[0].x
			let temY = e.changedTouches[0].y
			this.initPoint(temX, temY)
			this.onDraw()
		},
		uploadScaleEnd() {
			this.canAddHistory = true;
			if (this.points.length >= 2) {
				if (this.currentStroke.length > 0) {
					this.addHistory();
				}
			}
			this.points = [];
		},
		initPoint(x, y) {
			var point = {
				x: x,
				y: y,
				t: Date.now()
			};
			var prePoint = this.points.slice(-1)[0];
			if (prePoint && (prePoint.t === point.t || prePoint.x === x && prePoint.y === y)) {
				return;
			}
			if (prePoint && this.openSmooth) {
				var prePoint2 = this.points.slice(-2, -1)[0];
				// 使用工具类计算距离和速度
				point.distance = calculateDistance(point.x, point.y, prePoint.x, prePoint.y);
				point.speed = calculateSpeed(point.distance, point.t - prePoint.t);
				point.lineWidth = this.getLineWidth(point.speed);
				if (prePoint2 && prePoint2.lineWidth && prePoint.lineWidth) {
					var rate = (point.lineWidth - prePoint.lineWidth) / prePoint.lineWidth;
					var maxRate = this.maxWidthDiffRate / 100;
					maxRate = maxRate > 1 ? 1 : maxRate < 0.01 ? 0.01 : maxRate;
					if (Math.abs(rate) > maxRate) {
						var per = rate > 0 ? maxRate : -maxRate;
						point.lineWidth = prePoint.lineWidth * (1 + per);
					}
				}
			}
			this.points.push(point);
			this.points = this.points.slice(-3);
 
			this.currentStroke.push({
				x: point.x,
				y: point.y,
				t: point.t,
				lineWidth: point.lineWidth || this.minWidth,
				speed: point.speed || 0,
				distance: point.distance || 0
			});
		},
		getLineWidth(speed) {
			// 使用工具类计算线宽
			return calculateLineWidth(speed, this.minSpeed, this.minWidth, this.maxWidth);
		},
		onDraw() {
			if (this.points.length < 2) return;
 
			var point = this.points.slice(-1)[0];
			var prePoint = this.points.slice(-2, -1)[0];
			let that = this
			var onDraw = function onDraw() {
				if (that.openSmooth) {
					that.drawSmoothLine(prePoint, point);
				} else {
					that.drawNoSmoothLine(prePoint, point);
				}
			};
			if (typeof this.requestAnimationFrame === 'function') {
				this.requestAnimationFrame(function () {
					return onDraw();
				});
			} else {
				onDraw();
			}
		},
		//添加历史记录
		addHistory() {
			if (!this.maxHistoryLength || !this.canAddHistory) return;
 
			this.canAddHistory = false;
 
			// 统一使用笔画数据保存历史记录
			if (this.currentStroke.length > 0) {
				// 创建笔画对象，包含所有绘制信息
				const strokeData = {
					points: JSON.parse(JSON.stringify(this.currentStroke)), // 深拷贝点数据
					color: this.lineColor, // 当前笔画的颜色
					baseLineWidth: this.maxWidth, // 基础线条宽度
					minWidth: this.minWidth, // 最小线条宽度
					maxWidth: this.maxWidth, // 最大线条宽度
					openSmooth: this.openSmooth, // 是否开启平滑
					minSpeed: this.minSpeed, // 最小速度
					maxWidthDiffRate: this.maxWidthDiffRate, // 最大差异率
					timestamp: Date.now()
				};
 
				// 添加到绘制历史
				this.drawingHistory.push(strokeData);
 
				// 限制历史记录长度
				if (this.drawingHistory.length > this.maxHistoryLength) {
					this.drawingHistory = this.drawingHistory.slice(-this.maxHistoryLength);
				}
 
				// 同步更新historyList长度用于isEmpty检查
				this.historyList.length = this.drawingHistory.length;
 
				// 清空当前笔画
				this.currentStroke = [];
 
				console.log('Stroke added to history:', {
					strokeCount: this.drawingHistory.length,
					pointsInStroke: strokeData.points.length,
					color: strokeData.color
				});
			} else {
				console.log('No current stroke to add to history');
			}
 
			// 重置添加历史标志
			setTimeout(() => {
				this.canAddHistory = true;
			}, 100);
		},
		//画平滑线
		drawSmoothLine(prePoint, point) {
			var dis_x = point.x - prePoint.x;
			var dis_y = point.y - prePoint.y;
 
			if (Math.abs(dis_x) + Math.abs(dis_y) <= 2) {
				point.lastX1 = point.lastX2 = prePoint.x + dis_x * 0.5;
				point.lastY1 = point.lastY2 = prePoint.y + dis_y * 0.5;
			} else {
				point.lastX1 = prePoint.x + dis_x * 0.3;
				point.lastY1 = prePoint.y + dis_y * 0.3;
				point.lastX2 = prePoint.x + dis_x * 0.7;
				point.lastY2 = prePoint.y + dis_y * 0.7;
			}
			point.perLineWidth = (prePoint.lineWidth + point.lineWidth) / 2;
			if (typeof prePoint.lastX1 === 'number') {
				this.drawCurveLine(prePoint.lastX2, prePoint.lastY2, prePoint.x, prePoint.y, point.lastX1, point
					.lastY1, point.perLineWidth);
				if (prePoint.isFirstPoint) return;
				if (prePoint.lastX1 === prePoint.lastX2 && prePoint.lastY1 === prePoint.lastY2) return;
				var data = this.getRadianData(prePoint.lastX1, prePoint.lastY1, prePoint.lastX2, prePoint.lastY2);
				var points1 = this.getRadianPoints(data, prePoint.lastX1, prePoint.lastY1, prePoint.perLineWidth / 2);
				var points2 = this.getRadianPoints(data, prePoint.lastX2, prePoint.lastY2, point.perLineWidth / 2);
				this.drawTrapezoid(points1[0], points2[0], points2[1], points1[1]);
			} else {
				point.isFirstPoint = true;
			}
		},
		//画不平滑线
		drawNoSmoothLine(prePoint, point) {
			point.lastX = prePoint.x + (point.x - prePoint.x) * 0.5;
			point.lastY = prePoint.y + (point.y - prePoint.y) * 0.5;
			if (typeof prePoint.lastX === 'number') {
				this.drawCurveLine(prePoint.lastX, prePoint.lastY, prePoint.x, prePoint.y, point.lastX, point.lastY,
					this.maxWidth);
			}
		},
		//画线
		drawCurveLine(x1, y1, x2, y2, x3, y3, lineWidth, skipDraw = false) {
			if (!this.checkCanvasContext()) return;
 
			lineWidth = Number(lineWidth.toFixed(1));
			try {
				// 统一使用uni-app的canvas API
				if (this.ctx.setLineWidth) {
					this.ctx.setLineWidth(lineWidth);
				}
				this.ctx.lineWidth = lineWidth;
 
				// 确保线条样式设置正确，防止虚线效果
				this.ctx.setLineCap('round');
				this.ctx.setLineJoin('round');
				this.ctx.setStrokeStyle(this.lineColor);
 
				this.ctx.beginPath();
				this.ctx.moveTo(Number(x1.toFixed(1)), Number(y1.toFixed(1)));
				this.ctx.quadraticCurveTo(Number(x2.toFixed(1)), Number(y2.toFixed(1)), Number(x3.toFixed(1)), Number(y3
					.toFixed(1)));
				this.ctx.stroke();
 
				// 统一调用draw方法，但重绘时跳过
				if (this.ctx.draw && !skipDraw) {
					this.ctx.draw(true);
				}
			} catch (error) {
				console.error('Error in drawCurveLine:', error);
			}
		},
		//画梯形
		drawTrapezoid(point1, point2, point3, point4) {
			if (!this.checkCanvasContext()) return;
 
			this.ctx.beginPath();
			this.ctx.moveTo(Number(point1.x.toFixed(1)), Number(point1.y.toFixed(1)));
			this.ctx.lineTo(Number(point2.x.toFixed(1)), Number(point2.y.toFixed(1)));
			this.ctx.lineTo(Number(point3.x.toFixed(1)), Number(point3.y.toFixed(1)));
			this.ctx.lineTo(Number(point4.x.toFixed(1)), Number(point4.y.toFixed(1)));
 
			// 统一使用uni-app的canvas API
			this.ctx.setFillStyle(this.lineColor);
 
			this.ctx.fill();
			this.ctx.draw(true);
		},
		//画梯形（用于重绘，跳过draw调用）
		drawTrapezoidForRedraw(point1, point2, point3, point4) {
			if (!this.checkCanvasContext()) return;
 
			this.ctx.beginPath();
			this.ctx.moveTo(Number(point1.x.toFixed(1)), Number(point1.y.toFixed(1)));
			this.ctx.lineTo(Number(point2.x.toFixed(1)), Number(point2.y.toFixed(1)));
			this.ctx.lineTo(Number(point3.x.toFixed(1)), Number(point3.y.toFixed(1)));
			this.ctx.lineTo(Number(point4.x.toFixed(1)), Number(point4.y.toFixed(1)));
 
			// 统一使用uni-app的canvas API
			this.ctx.setFillStyle(this.lineColor);
 
			this.ctx.fill();
			// 重绘时跳过单独的draw调用，统一在redrawAllStrokes中调用
		},
		//获取弧度
		getRadianData(x1, y1, x2, y2) {
			// 使用工具类获取弧度数据
			return getRadianData(x1, y1, x2, y2);
		},
		//获取弧度点
		getRadianPoints(radianData, x, y, halfLineWidth) {
			// 使用工具类获取弧度点
			return getRadianPoints(radianData, x, y, halfLineWidth);
		},
		/**
		 * 背景色
		 */
		drawBgColor() {
			const config = this.getCurrentConfig();
			if (!this.ctx || !config.bgColor) return;
 
			// 直接使用 canvas API 绘制背景色
			this.ctx.setFillStyle(config.bgColor);
			this.ctx.fillRect(0, 0, this.canvasWidth, this.canvasHeight);
			this.ctx.draw(true); // 保留之前的绘制内容
		},
		//图片绘制
		// drawByImage(url) {
		// 	if (!this.ctx || !url) return;
 
		// 	// 直接使用 canvas API 绘制图片
		// 	this.ctx.drawImage(url, 0, 0, this.canvasWidth, this.canvasHeight);
		// 	this.ctx.draw(true); // 保留之前的绘制内容
		// },
		/**
		 * 清空画布
		 */
		clear() {
			if (!this.isCanvasReady) {
				showToast('画布未就绪，请稍后再试', 'none', 2000);
				return;
			}
 
			if (!this.checkCanvasContext()) return;
 
			try {
				// 使用工具类清空画布
				clearCanvasArea(this.ctx, 0, 0, this.canvasWidth, this.canvasHeight);
 
				// 重新绘制背景色（如果不是透明的话）
				this.drawBgColor();
 
				// 清空所有历史记录和当前绘制点
				this.historyList.length = 0;
				this.drawingHistory = []; // 清空绘制历史
				this.currentStroke = []; // 清空当前笔画
				this.points = [];
 
				showToast('画布已清空', 'success', 1500);
			} catch (error) {
				console.error('Error clearing canvas:', error);
				showToast('清空失败，请重试', 'none', 2000);
			}
		},
		// 清空画布（不清除历史记录）
		clearCanvas() {
			if (!this.ctx) {
				console.error('Canvas context not available for clearing');
				return;
			}
 
			try {
				// 使用工具类清空画布
				clearCanvasArea(this.ctx, 0, 0, this.canvasWidth, this.canvasHeight);
				console.log('Canvas cleared successfully with transparent background');
			} catch (error) {
				console.error('Error clearing canvas:', error);
			}
		},
		// 重新绘制所有历史笔画
		redrawAllStrokes() {
			if (!this.ctx || this.drawingHistory.length === 0) {
				console.log('No context or no history to redraw');
				return;
			}
 
			console.log('Redrawing', this.drawingHistory.length, 'strokes');
 
			try {
				// 清空画布
				this.clearCanvas();
 
				// 如果需要背景色则绘制（透明背景时跳过）
				if (this.bgColor && this.bgColor !== 'transparent' && this.bgColor !== 'rgba(0,0,0,0)') {
					this.drawBgColor();
				}
 
				// 遍历所有历史笔画
				for (let i = 0; i < this.drawingHistory.length; i++) {
					const stroke = this.drawingHistory[i];
					this.redrawSingleStroke(stroke, i);
				}
 
				// 统一使用uni-app的canvas API调用draw()来应用绘制
				this.ctx.draw();
 
				console.log('All strokes redrawn successfully');
			} catch (error) {
				console.error('Error redrawing strokes:', error);
			}
		},
		// 重新绘制单个笔画
		redrawSingleStroke(stroke, strokeIndex) {
			if (!stroke || !stroke.points || stroke.points.length < 2) {
				console.log('Invalid stroke data for redraw:', strokeIndex);
				return;
			}
 
			try {
				// 设置笔画颜色
				this.ctx.setStrokeStyle(stroke.color || this.lineColor);
				this.ctx.setLineCap('round');
				this.ctx.setLineJoin('round');
 
				if (stroke.openSmooth && stroke.points.length > 2) {
					// 平滑绘制 - 完全模拟原始绘制过程
					this.redrawSmoothStrokeAccurate(stroke);
				} else {
					// 直线绘制 - 使用笔画的基础线条宽度
					this.ctx.setLineWidth(stroke.baseLineWidth || stroke.lineWidth || this.maxWidth);
					this.ctx.beginPath();
					this.redrawStraightStroke(stroke.points);
					this.ctx.stroke();
				}
 
				console.log('Stroke', strokeIndex, 'redrawn with', stroke.points.length, 'points');
			} catch (error) {
				console.error('Error redrawing single stroke:', strokeIndex, error);
			}
		},
		// 重新绘制平滑笔画
		redrawSmoothStroke(points) {
			if (points.length < 2) return;
 
			this.ctx.moveTo(points[0].x, points[0].y);
 
			for (let i = 1; i < points.length - 1; i++) {
				const currentPoint = points[i];
				const nextPoint = points[i + 1];
				const controlX = (currentPoint.x + nextPoint.x) / 2;
				const controlY = (currentPoint.y + nextPoint.y) / 2;
 
				this.ctx.quadraticCurveTo(currentPoint.x, currentPoint.y, controlX, controlY);
			}
 
			// 绘制最后一个点
			if (points.length > 1) {
				const lastPoint = points[points.length - 1];
				this.ctx.lineTo(lastPoint.x, lastPoint.y);
			}
		},
 
		// 重新绘制带宽度的平滑笔画
		redrawSmoothStrokeWithWidth(points) {
			if (points.length < 2) return;
 
			// 遍历所有点，使用每个点保存的线条宽度进行绘制
			for (let i = 0; i < points.length - 1; i++) {
				const currentPoint = points[i];
				const nextPoint = points[i + 1];
 
				// 使用当前点的线条宽度，如果没有则使用默认值
				const lineWidth = currentPoint.lineWidth || this.maxWidth;
				this.ctx.setLineWidth(lineWidth);
 
				this.ctx.beginPath();
				this.ctx.moveTo(currentPoint.x, currentPoint.y);
 
				if (i < points.length - 2) {
					// 不是最后一段，使用平滑曲线
					const controlPoint = points[i + 1];
					const endPoint = points[i + 2];
					const controlX = (controlPoint.x + endPoint.x) / 2;
					const controlY = (controlPoint.y + endPoint.y) / 2;
 
					this.ctx.quadraticCurveTo(controlPoint.x, controlPoint.y, controlX, controlY);
				} else {
					// 最后一段，直接连线
					this.ctx.lineTo(nextPoint.x, nextPoint.y);
				}
 
				this.ctx.stroke();
			}
		},
 
		// 精确重绘平滑笔画 - 完全模拟原始绘制过程
		redrawSmoothStrokeAccurate(stroke) {
			if (!stroke.points || stroke.points.length < 2) return;
 
			const points = stroke.points;
			// 保存当前线条颜色，确保重绘时使用正确的颜色
			const originalColor = this.lineColor;
			this.lineColor = stroke.color || originalColor;
 
			// 模拟原始的绘制过程，逐段绘制
			for (let i = 1; i < points.length; i++) {
				const prePoint = points[i - 1];
				const point = points[i];
 
				// 重建点的完整信息（模拟initPoint的处理）
				if (stroke.openSmooth && i < points.length - 1) {
					// 计算控制点信息（模拟drawSmoothLine的逻辑）
					const dis_x = point.x - prePoint.x;
					const dis_y = point.y - prePoint.y;
 
					if (Math.abs(dis_x) + Math.abs(dis_y) <= 2) {
						point.lastX1 = point.lastX2 = prePoint.x + dis_x * 0.5;
						point.lastY1 = point.lastY2 = prePoint.y + dis_y * 0.5;
					} else {
						point.lastX1 = prePoint.x + dis_x * 0.3;
						point.lastY1 = prePoint.y + dis_y * 0.3;
						point.lastX2 = prePoint.x + dis_x * 0.7;
						point.lastY2 = prePoint.y + dis_y * 0.7;
					}
 
					// 计算平均线条宽度
					point.perLineWidth = ((prePoint.lineWidth || stroke.minWidth || this.minWidth) +
						(point.lineWidth || stroke.minWidth || this.minWidth)) / 2;
 
					// 使用原始的drawCurveLine逻辑，跳过单独的draw调用
					if (typeof prePoint.lastX1 === 'number') {
						this.drawCurveLine(prePoint.lastX2, prePoint.lastY2, prePoint.x, prePoint.y,
							point.lastX1, point.lastY1, point.perLineWidth, true);
 
						// 添加梯形绘制逻辑，确保线条连续性和粗细一致
						if (!prePoint.isFirstPoint) {
							if (!(prePoint.lastX1 === prePoint.lastX2 && prePoint.lastY1 === prePoint.lastY2)) {
								var data = this.getRadianData(prePoint.lastX1, prePoint.lastY1, prePoint.lastX2, prePoint.lastY2);
								var points1 = this.getRadianPoints(data, prePoint.lastX1, prePoint.lastY1, prePoint.perLineWidth / 2);
								var points2 = this.getRadianPoints(data, prePoint.lastX2, prePoint.lastY2, point.perLineWidth / 2);
 
								// 绘制梯形填充，但跳过单独的draw调用
								this.drawTrapezoidForRedraw(points1[0], points2[0], points2[1], points1[1]);
							}
						} else {
							// 标记第一个点
							point.isFirstPoint = true;
						}
					}
				} else {
					// 非平滑模式，直接绘制线段
					const lineWidth = point.lineWidth || stroke.baseLineWidth || this.maxWidth;
					this.drawCurveLine(prePoint.x, prePoint.y, prePoint.x, prePoint.y,
						point.x, point.y, lineWidth, true);
				}
			}
 
			// 恢复原始线条颜色
			this.lineColor = originalColor;
		},
		// 重新绘制直线笔画
		redrawStraightStroke(points) {
			if (points.length < 2) return;
 
			this.ctx.moveTo(points[0].x, points[0].y);
 
			for (let i = 1; i < points.length; i++) {
				this.ctx.lineTo(points[i].x, points[i].y);
			}
		},
		//撤消
		undo() {
			if (!this.isCanvasReady) {
				showToast('画布未就绪，请稍后再试', 'none', 2000);
				return;
			}
 
			// 检查是否有可撤销的操作
			if (this.isEmpty()) {
				showToast('没有可撤销的操作', 'none', 1500);
				return;
			}
 
			if (!this.checkCanvasContext()) return;
 
			try {
				// 统一使用uni-app的canvas API，实现真正的逐步撤销
				if (this.drawingHistory.length > 0) {
					// 移除最后一个绘制操作
					const removedStroke = this.drawingHistory.pop();
					console.log('Removed stroke from history:', {
						remainingStrokes: this.drawingHistory.length,
						removedPoints: removedStroke.points.length
					});
 
					// 同步更新historyList长度
					this.historyList.length = this.drawingHistory.length;
 
					// 清空画布
					this.clearCanvas();
 
					// 重新绘制剩余的所有操作
					this.redrawAllStrokes();
 
					showToast('已撤销上一步', 'success', 1500);
 
					console.log('Undo completed, remaining strokes:', this.drawingHistory.length);
				} else {
					showToast('没有可撤销的操作', 'none', 1500);
				}
			} catch (error) {
				console.error('Error in undo:', error);
				showToast('撤销失败，请重试', 'none', 2000);
			}
		},
 
		//是否为空
		isEmpty() {
			// 统一使用uni-app的canvas API检查空画布逻辑
			const hasDrawing = this.drawingHistory.length > 0 || this.currentStroke.length > 0;
 
			console.log('[签名组件] Canvas isEmpty 详细检查:', {
				isEmpty: !hasDrawing,
				historyListLength: this.historyList.length,
				drawingHistoryLength: this.drawingHistory.length,
				currentStrokeLength: this.currentStroke.length,
				hasDrawing: hasDrawing
			});
			return !hasDrawing;
		},
 
		/**
		 * @param {Object} str
		 * @param {Object} color
		 * 选择颜色
		 */
		selectColorEvent(str, color) {
			this.selectColor = str;
			this.lineColor = color;
 
			if (this.checkCanvasContext()) {
				try {
					this.ctx.setStrokeStyle(this.lineColor);
 
					uni.showToast({
						title: `已选择${str === 'black' ? '黑色' : '红色'}`,
						icon: 'success',
						duration: 1000
					});
				} catch (error) {
					console.error('Error setting color:', error);
				}
			}
		},
 
 
 
 
 
		//保存到相册
		saveCanvasAsImg() {
			if (!this.isCanvasReady) {
				showToast('画布未就绪，请稍后再试', 'none', 2000);
				return;
			}
 
			if (this.isEmpty()) {
				showToast('没有任何绘制内容哦', 'none', 2000);
				return;
			}
 
			if (!this.checkCanvasContext()) return;
 
			// 统一使用uni-app方法保存
			this.performSave();
		},
		// 执行保存操作（统一入口）
		performSave() {
			// 基础验证
			if (!this.isCanvasReady) {
				showToast('画布未就绪，请稍后再试', 'none', 2000);
				return;
			}
			if (this.isEmpty()) {
				showToast('没有任何绘制内容哦', 'none', 2000);
				return;
			}
			if (!this.checkCanvasContext()) return;
			showLoading('正在保存...');
			
			// 统一使用uni.canvasToTempFilePath API
			const canvasOptions = {
				canvasId: 'handWriting',
				fileType: 'png',
				quality: 1,
				success: (res) => {
					hideLoading();
					// #ifdef H5
					// H5环境：创建下载链接
					const link = document.createElement('a');
					link.download = `signature_${Date.now()}.png`;
					link.href = res.tempFilePath;
					document.body.appendChild(link);
					link.click();
					document.body.removeChild(link);
					showToast('签名已下载', 'success', 2000);
					// #endif
					// #ifndef H5
					// 小程序环境：保存到相册
					uni.saveImageToPhotosAlbum({
						filePath: res.tempFilePath,
						success: (saveRes) => {
							showToast('已成功保存到相册', 'success', 2000);
						},
						fail: (saveError) => {
							if (saveError.errMsg.includes('auth')) {
								showModal('保存失败', '需要相册权限，请在设置中开启', '去设置')
									.then((modalRes) => {
										if (modalRes.confirm) {
											uni.openSetting();
										}
									});
							} else {
								showToast('保存失败，请重试', 'none', 2000);
							}
						}
					});
					// #endif
				},
				fail: (error) => {
					hideLoading();
					console.error('[保存失败]:', error);
					showToast('生成签名图片失败', 'none', 2000);
				}
			};
			uni.canvasToTempFilePath(canvasOptions, this);
 
		},
		//预览
		previewCanvasImg() {
			if (!this.isCanvasReady) {
				showToast('画布未就绪，请稍后再试', 'none', 2000);
				return;
			}
			if (this.isEmpty()) {
				showToast('没有任何绘制内容哦', 'none', 2000);
				return;
			}
			if (!this.checkCanvasContext()) return;
			showLoading('正在生成预览...');
			const canvasOptions = {
				canvasId: 'handWriting',
				fileType: 'png', // 改为png格式，兼容性更好
				quality: 1,
				success: (res) => {
					console.log(res)
					hideLoading();
					uni.previewImage({
						urls: [res.tempFilePath],
						current: 0,
						success: (res) => {
							console.log(res, 'res')
						},
						fail: (error) => {
							showToast('预览失败，请重试', 'none', 2000);
						}
					});
				},
				fail: (error) => {
					hideLoading();
					console.error('Canvas to temp file failed:', error);
					showToast('生成预览图片失败', 'none', 2000);
				}
			};
 
			// 统一使用uni.canvasToTempFilePath
			uni.canvasToTempFilePath(canvasOptions, this);
		},
 
		// 完成签名
		complete() {
			if (!this.isCanvasReady) {
				showToast('画布未就绪，请稍后再试', 'none', 2000);
				return;
			}
 
			if (this.isEmpty()) {
				showToast('请先进行签名', 'none', 2000);
				return;
			}
 
			if (!this.checkCanvasContext()) return;
 
			showLoading('正在生成签名...');
 
			const canvasOptions = {
				canvasId: 'handWriting',
				fileType: 'png',
				quality: 1,
				success: (res) => {
					// 生成签名图片成功后，上传到服务器
					this.uploadSignatureImage(res.tempFilePath);
				},
				fail: (error) => {
					hideLoading();
					console.error('Canvas to temp file failed:', error);
					showToast('生成签名失败，请重试', 'none', 2000);
				}
			};
 
			// 统一使用uni.canvasToTempFilePath
			uni.canvasToTempFilePath(canvasOptions, this);
		},
 
		// 上传签名图片到服务器
		uploadSignatureImage(filePath) {
			const config = this.getCurrentConfig();
 
			// 使用UploadManager处理上传
			this.uploadManager.performUpload(filePath, config)
				.then(result => {
					hideLoading();
					this.$emit('complete', {
						filePath: result.fileUrl,
						success: true,
						response: result.response,
						retryCount: result.retryCount,
						uploadTime: result.uploadTime
					});
					showToast('签名上传成功', 'success', 2000);
				})
				.catch(error => {
					hideLoading();
					const errorMsg = formatErrorMessage(error.message || error.toString());
					showFinalError(errorMsg, this.getCurrentConfig());
					this.$emit('complete', {
						success: false,
						error: error.message,
						originalError: error,
						retryCount: error.retryCount || 0
					});
				});
		},
 
 
 
 
 
 
 
 
 
 
 
	},
	mounted() {
		console.log('[签名组件] mounted 开始执行');
		// 合并配置
		this.mergeConfig();
		// 初始化上传管理器
		this.uploadManager = new UploadManager();
		this.initCanvas();
	},
};
</script>
 
<style lang="scss" scoped>
page {
	background: #fbfbfb;
	height: auto;
	overflow: hidden;
}
 
.wrapper {
	display: flex;
	height: 100%;
	align-content: center;
	flex-direction: row;
	justify-content: center;
	font-size: 28rpx;
	z-index: 999999;
	border: 2rpx dashed #666;
	background-color: rgba(0, 0, 0, 0.05);
 
}
 
.handWriting {
	background: #fff;
	width: 100%;
	height: 100%;
}
 
.handRight {
	display: inline-flex;
	align-items: center;
}
 
.handCenter {
	border: 4rpx dashed #e9e9e9;
	flex: 5;
	overflow: hidden;
	box-sizing: border-box;
}
 
.handTitle {
	transform: rotate(90deg);
	flex: 1;
	color: #666;
}
 
 
 
.handBtn {
	height: 95vh;
	display: inline-flex;
	flex-direction: column;
	justify-content: center;
	align-content: center;
	align-items: center;
	flex: 1;
	gap: 100rpx;
}
 
.handBtn button {
	font-size: 28rpx;
	color: #666;
	background-color: transparent;
	border: none;
	transform: rotate(90deg);
	width: 150rpx;
	height: 70rpx;
}
 
/* 各个按钮的字体白色 背景色 */
.handBtn button:nth-child(1) {
	color: #fff;
	background-color: #007AFF;
}
 
.handBtn button:nth-child(2) {
	color: #fff;
	background-color: #FF4D4F;
}
 
.handBtn button:nth-child(3) {
	color: #fff;
	background-color: #00C49F;
}
 
.handBtn button:nth-child(4) {
	color: #fff;
	background-color: #FF9900;
}
 
.handBtn button:nth-child(5) {
	color: #fff;
	background-color: #9900FF;
}
</style>